import json

from django.contrib.auth import login
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View
from django import http
import re
import logging
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from django_redis import get_redis_connection

from apps.users.models import User
from meiduo_mall import settings
from utils.response_code import RETCODE
from django.contrib.auth import authenticate

loger = logging.getLogger('django')


class RegisterView(View):
    def get(self, request):
        return render(request, 'register.html')
        # return render(request, 'register.html')

    def post(self, request):
        # 接收数据
        username = request.POST.get('username')
        password = request.POST.get('password')
        password2 = request.POST.get('password2')
        mobile = request.POST.get('mobile')
        allow = request.POST.get('allow')
        # 验证数据
        if not all([username, password, password2, mobile]):
            return http.JsonResponse({'code': RETCODE.NECESSARYPARAMERR, 'errmsg': '参数不全'})
        if not re.match(r'[a-zA-Z0-9_]{5,20}', username):
            return http.JsonResponse({'code': RETCODE.USERERR, 'errmsg': '用户名错误'})
        if not re.match(r'[a-zA-Z0-9]{8,20}', password):
            return http.JsonResponse({'code': RETCODE.PWDERR, 'errmsg': '密码错误'})
        if password != password2:
            return http.JsonResponse({'code': RETCODE.PWDERR, 'errmsg': '密码错误'})
        if not re.match(r'1[3456789]\d{9}', mobile):
            return http.JsonResponse({'code': RETCODE.MOBILEERR, 'errmsg': '手机错误'})
        if allow != 'on':
            return http.JsonResponse({'code': RETCODE.ALLOWERR, 'errmsg': '协议错误'})
        # 数据入库
        try:
            user = User.objects.create_user(
                username=username,
                password=password,
                mobile=mobile
            )
        except Exception:
            return http.HttpResponseBadRequest('发生错误')

        login(request, user)

        return redirect(reverse('contents:index'))


class UsernameCountView(View):
    def get(self, request, username):
        count = User.objects.filter(username=username).count()
        return http.JsonResponse({'count': count})


class MobileCountView(View):
    def get(self, request, mobile):
        count = User.objects.filter(mobile=mobile).count()
        return http.JsonResponse({'count': count})


class UserView(View):
    def get(self, request):

        return render(request, 'login.html')

    def post(self, request):
        # 接收数据
        username = request.POST.get('username')
        password = request.POST.get('pwd')

        remembered = request.POST.get('remembered')

        # 验证数据
        if not all([username, password]):
            return http.JsonResponse({'code': RETCODE.NECESSARYPARAMERR, 'errmsg': '参数不全'})
        if not re.match(r'[a-zA-Z0-9_]{5,20}', username):
            return http.JsonResponse({'code': RETCODE.USERERR, 'errmsg': '用户名错误'})
        if not re.match(r'[a-zA-Z0-9]{8,20}', password):
            return http.JsonResponse({'code': RETCODE.PWDERR, 'errmsg': '密码错误'})

        user = authenticate(username=username, password=password)
        if user is None:
            return http.JsonResponse({'code': RETCODE.USERERR, 'errmsg': '用户不存在'})

        login(request, user)

        if remembered != 'on':
            request.session.set_expiry(0)
        else:
            request.session.set_expiry(None)

        return redirect(reverse('contents:index'))


class ChangePWDView(View):
    def get(self, request):
        return render(request, 'find_password.html')


class COPWDView(View):
    # 图片验证
    def get(self, request, username):
        # 获取参数
        image_code = request.GET.get('text')
        uuid = request.GET.get('image_code_id')
        # 校验参数 用户名
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return http.HttpResponseBadRequest('用户名错误')
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            return http.HttpResponseBadRequest('用户不存在')
        # 校验图片验证码
        conn = get_redis_connection('code')
        image_server = conn.get('img_%s' % uuid)

        if image_server is None:
            return http.HttpResponseBadRequest('验证码已过期')
        try:
            conn.delete('img_%s' % uuid)
        except Exception:
            return http.HttpResponseBadRequest('发生错误')

        image_server = image_server.decode()
        if image_server.lower() != image_code.lower():
            return http.HttpResponseBadRequest('验证码错误')
        #
        serializer = Serializer(settings.SECRET_KEY)
        data = {'user_id': user.id, 'mobile': user.mobile}
        token = serializer.dumps(data).decode()

        return http.JsonResponse({
            'mobile': user.mobile,
            'access_token': token
        })


class CTwoPWDView(View):
    # 短信验证
    def get(self, request, username):
        # 接受参数
        user = User.objects.get(username=username)
        sms_code = request.GET.get('sms_code')
        mobile = user.mobile
        conn = get_redis_connection('code')
        sms_server = conn.get('sms_%s' % mobile)
        # 校验参数
        if sms_server is None:
            return http.JsonResponse({'code': RETCODE.SMSCODERR, 'errmsg': '验证码错误'})
        if sms_code != sms_server.decode():
            return http.JsonResponse({'code': RETCODE.SMSCODERR, 'errmsg': '验证码错误'})
        # 设置参数
        serializer = Serializer(settings.SECRET_KEY)
        data = {'user_id': user.id, 'mobile': user.mobile}
        token = serializer.dumps(data).decode()

        return http.JsonResponse({
            'user_id': user.id,
            'access_token': token
        })


class CFinPWDView(View):
    # 重置密码
    def post(self, request, user_id):
        # 接受参数
        dict = json.loads(request.body.decode())
        pwd = dict.get('password')
        pwd2 = dict.get('password2')
        # 校验参数
        if not all([pwd, pwd2]):
            return http.HttpResponseBadRequest('参数不全')
        # 判断密码是否是8-20个数字
        if not re.match(r'^[0-9A-Za-z]{8,20}$', pwd):
            return http.JsonResponse({'code': RETCODE.PWDERR, 'errmsg': '密码错误'})
        # 判断两次密码是否一致
        if pwd != pwd2:
            return http.JsonResponse({'code': RETCODE.CPWDERR, 'errmsg': '确认密码错误'})
        # 重置用户密码
        try:
            user = User.objects.get(pk=user_id)
        except:
            return http.JsonResponse({'code': RETCODE.USERERR, 'errmsg': '用户不存在'})

        try:
            user.set_password(pwd)
        except:
            return http.JsonResponse({'code': RETCODE.PWDERR, 'errmsg': '重置失败'})

        user.save()
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'ok'})


class UserCenterView(LoginRequiredMixin, View):
    def get(self, request):
        """提供个人信息界面"""
        context = {
            'username': request.user.username,
            'mobile': request.user.mobile,
            'email': request.user.email,
            'email_active': request.user.email_active
        }
        return render(request, 'user_center_info.html', context=context)



